// OK, let's try all this using Java-style iterators.  From what
// I recall, such iterators use pointers instead of values.
// They can have memory leaks, though, because they are allocated
// on the stack.

#include <list>
#include <iostream>
#include "Graph.h"

class Iterator {
public:
    virtual ~Iterator() {};
    virtual bool has_next() = 0;
    virtual int get_next() = 0;
};

class Iterator_List : public Iterator {
private:
    std::list<int>::iterator begin;
    std::list<int>::iterator end;
    std::list<int>::iterator next;

public:
    Iterator_List(std::list<int>::iterator begin,
                  std::list<int>::iterator end);
    ~Iterator_List() {};

    bool has_next();
    int get_next();
};

Iterator_List::Iterator_List(std::list<int>::iterator begin,
                             std::list<int>::iterator end) {
    this->begin = begin;
    this->end = end;
    next = begin;
}

bool Iterator_List::has_next() {
    return next != end;
}

int Iterator_List::get_next() {
    return *next++;
}

class Bunch {
public:
    virtual ~Bunch() {};
    virtual Iterator *get_iterator() = 0;
    virtual void add(int x) = 0;
};

class Bunch_List : public Bunch {
public:
    Iterator *get_iterator();
    void add(int x);

private:
    std::list<int> items;
};


Iterator *Bunch_List::get_iterator() {
    return new Iterator_List(items.begin(), items.end());
}

void Bunch_List::add(int x) {
    items.push_back(x);
}

int main() {
    // std::list<int> l;
    // l.push_back(1);
    // l.push_back(2);
    // l.push_back(3);

    // Iterator_List<int> *iter = new Iterator_List<int>(l.begin(), l.end());

    Bunch_List lis;

    lis.add(1);
    lis.add(2);
    lis.add(3);

    Iterator *iter = lis.get_iterator();
    while (iter->has_next())
        std::cout << iter->get_next() << " ";
    std::cout << "\n";
    delete iter;
}

